// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CloudBlobExtensions.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   Exception for errors when handling Windows Azure Cloud Drives.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;

using AzureContrib.WindowsAzure.StorageClient.Properties;

using Microsoft.WindowsAzure.StorageClient;

namespace AzureContrib.WindowsAzure.StorageClient
{
	/// <summary>
	/// Extensions for <see cref="CloudBlob"/>
	/// </summary>
	public static class CloudBlobExtensions
	{
		/// <summary>
		/// Does the <see cref="CloudBlob"/> exist in blob storage?
		/// </summary>
		/// <param name="cloudBlob">The blob to check for.</param>
		/// <returns>True if the actual blob file exists and is a <see cref="BlobType.PageBlob"/>.</returns>
		public static bool Exists(this CloudBlob cloudBlob)
		{
			return Exists(cloudBlob, BlobType.Unspecified);
		}

		/// <summary>
		/// Does the <see cref="CloudBlob"/> exist in blob storage?
		/// </summary>
		/// <param name="cloudBlob">The blob to check for.</param>
		/// <param name="blobType">The type of blob we are expecting the blob to be.</param>
		/// <returns>True if the actual blob file exists and is a <see cref="BlobType.PageBlob"/>.</returns>
		[SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods", Justification = "Assumes.NotNull handles null checking.", Scope = "method")]
		public static bool Exists(this CloudBlob cloudBlob, BlobType blobType)
		{
			try
			{
				Assumes.NotNull(cloudBlob, "cloudBlob");

				// If attributes are already fetched they cannot be fetched again!
				if (cloudBlob.Attributes.Properties.Length > 0)
				{
					var newCloudBlob = new CloudBlob(cloudBlob.Uri.AbsoluteUri, cloudBlob.ServiceClient.Credentials);
					return Exists(newCloudBlob);
				}

				cloudBlob.FetchAttributes();
				if (blobType != BlobType.Unspecified && cloudBlob.Attributes.Properties.BlobType != blobType)
				{
					Trace.TraceError(Strings.NotTheRightBlobType, cloudBlob.Uri.AbsoluteUri, blobType);
					return false;
				}

				return true;
			}
			catch (StorageClientException e)
			{
				if (e.ErrorCode == StorageErrorCode.ResourceNotFound)
				{
					Trace.TraceInformation(Strings.BlobContainerDoesNotExist, cloudBlob.Uri.AbsoluteUri);
					return false;
				}

				Trace.TraceError(Strings.LocatingBlobContainerThrewException, cloudBlob.Uri.AbsoluteUri, e.GetType(), e.Message);
				throw;
			}
		}
	}
}